home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / pctv3n2.zip / L4.CPP < prev    next >
Text File  |  1992-03-21  |  3KB  |  81 lines

  1. /* next_generation(), implemented using fast, all-in-one hard-wired
  2.    neighbor count/update/draw function. Otherwise, the same as
  3.    Listing 3. */
  4.  
  5. /* Calculates the next generation of current_map and stores it in
  6.    next_map. */
  7. void cellmap::next_generation(cellmap& next_map)
  8. {
  9.    unsigned int x, y, neighbor_count;
  10.    unsigned int width_in_bytesX2 = width_in_bytes << 1;
  11.    unsigned char *cell_ptr, *current_cell_ptr, mask, current_mask;
  12.    unsigned char *base_cell_ptr, *row_cell_ptr, base_mask;
  13.    unsigned char *dest_cell_ptr = next_map.cells;
  14.  
  15.    // Process all cells in the current cellmap
  16.    row_cell_ptr = cells;      // point to upper left neighbor of
  17.                               // first cell in cell map
  18.    for (y=0; y<height; y++) { // repeat for each row of cells
  19.       // Cell pointer and cell bit mask for first cell in row
  20.       base_cell_ptr = row_cell_ptr; // to access upper left neighbor
  21.       base_mask = 0x01;             // of first cell in row
  22.       for (x=0; x<width; x++) {  // repeat for each cell in row
  23.          // First, count neighbors
  24.          // Point to upper left neighbor of current cell
  25.          cell_ptr = base_cell_ptr;  // pointer and bit mask for
  26.          mask = base_mask;          // upper left neighbor
  27.          // Count upper left neighbor
  28.          neighbor_count = (*cell_ptr & mask) ? 1 : 0;
  29.          // Count left neighbor
  30.          if ((*(cell_ptr + width_in_bytes) & mask)) neighbor_count++;
  31.          // Count lower left neighbor
  32.          if ((*(cell_ptr + width_in_bytesX2) & mask))
  33.                neighbor_count++;
  34.          // Point to upper neighbor
  35.          if ((mask >>= 1) == 0) {
  36.             mask = 0x80;
  37.             cell_ptr++;
  38.          }
  39.          // Remember where to find the current cell
  40.          current_cell_ptr = cell_ptr + width_in_bytes;
  41.          current_mask = mask;
  42.          // Count upper neighbor
  43.          if ((*cell_ptr & mask)) neighbor_count++;
  44.          // Count lower neighbor
  45.          if ((*(cell_ptr + width_in_bytesX2) & mask))
  46.                neighbor_count++;
  47.          // Point to upper right neighbor
  48.          if ((mask >>= 1) == 0) {
  49.             mask = 0x80;
  50.             cell_ptr++;
  51.          }
  52.          // Count upper right neighbor
  53.          if ((*cell_ptr & mask)) neighbor_count++;
  54.          // Count right neighbor
  55.          if ((*(cell_ptr + width_in_bytes) & mask)) neighbor_count++;
  56.          // Count lower right neighbor
  57.          if ((*(cell_ptr + width_in_bytesX2) & mask))
  58.                neighbor_count++;
  59.          if (*current_cell_ptr & current_mask) {
  60.             if ((neighbor_count != 2) && (neighbor_count != 3)) {
  61.                *(dest_cell_ptr + (current_cell_ptr - cells)) &=
  62.                      ~current_mask;    // turn off cell
  63.                draw_pixel(x, y, OFF_COLOR);
  64.             }
  65.          } else {
  66.             if (neighbor_count == 3) {
  67.                *(dest_cell_ptr + (current_cell_ptr - cells)) |=
  68.                      current_mask;     // turn on cell
  69.                draw_pixel(x, y, ON_COLOR);
  70.             }
  71.          }
  72.          // Advance to the next cell on row
  73.          if ((base_mask >>= 1) == 0) {
  74.             base_mask = 0x80;
  75.             base_cell_ptr++;  // advance to the next cell byte
  76.          }
  77.       }
  78.       row_cell_ptr += width_in_bytes;  // point to start of next row
  79.    }
  80. }
  81.